﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using UtilZ.Dotnet.Ex.Communication.Net.FastTransfer;
using UtilZ.Dotnet.Ex.Log;

namespace DotnetWinFormApp
{
    public partial class FTestFastTransfer : Form
    {
        public FTestFastTransfer()
        {
            InitializeComponent();
        }

        private void FTestFastTransfer_Load(object sender, EventArgs e)
        {
            var redirectAppenderToUI = (RedirectAppender)Loger.GetAppenderByName(null, "RedirectToUI");
            if (redirectAppenderToUI != null)
            {
                redirectAppenderToUI.RedirectOuput += RedirectLogOutput;
            }
        }

        private void RedirectLogOutput(object sender, RedirectOuputArgs e)
        {
            try
            {
                string str;
                try
                {
                    str = string.Format("{0} {1}", DateTime.Now, e.Item.Content);
                }
                catch (Exception ex)
                {
                    str = ex.Message;
                }

                logControl1.AddLog(str, e.Item.Level);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            logControl1.Clear();
        }

        private TransferPolicy _textTransferPolicy = null;
        private TransferPolicy _fileTransferPolicy = null;
        private TransferChannel _transferChannel;
        private void btnInit_Click(object sender, EventArgs e)
        {
            try
            {
                var remoteEndPoint = new IPEndPoint(IPAddress.Parse(txtDstIP.Text), (int)numSendPort.Value);
                this._textTransferPolicy = new TransferPolicy(remoteEndPoint, 1, 1000, 3);
                this._fileTransferPolicy = new TransferPolicy(remoteEndPoint, 10, 10000, 3);//文件发送时超时时长要长一些，否则大文件容易失败

                var config = new TransferConfig();
                config.NetConfig.ListenEP = new IPEndPoint(IPAddress.Any, (int)numRevPort.Value);
                this._transferChannel = new TransferChannel(config, this.ReceiveTransferDataCallback);
                this._transferChannel.Start();
                Loger.Info("初始化完成");
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void ReceiveTransferDataCallback(ReceiveDataItem dataItem)
        {
            try
            {
                if (dataItem.Flag)
                {
                    string str = Encoding.UTF8.GetString(dataItem.Data);
                    Loger.Info($"收到文本:{str}");
                }
                else
                {
                    Loger.Info($"收到文件:{dataItem.FilePath}");
                }
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void btnSendText_Click(object sender, EventArgs e)
        {
            try
            {
                string text = txtText.Text;
                byte[] buffer = Encoding.UTF8.GetBytes(text);
                this._transferChannel.SendData(buffer, this._textTransferPolicy);
                //失败会抛出异常
                Loger.Info($"发送文本\"{text}\"完成");
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void btnChioceFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;
            if (ofd.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            txtFlePath.Text = ofd.FileName;
        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            try
            {
                string filePath = txtFlePath.Text.Trim();
                if (string.IsNullOrWhiteSpace(filePath))
                {
                    Loger.Warn("文件路径不能为空");
                    return;
                }

                if (!File.Exists(filePath))
                {
                    Loger.Warn($"文件{filePath}不存在");
                    return;
                }

                btnSendFile.Enabled = false;
                Task.Factory.StartNew(this.SendFile, filePath);
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void SendFile(object obj)
        {
            var filePath = (string)obj;
            try
            {
                Loger.Info($"发送文件\"{filePath}\"开始...");
                //失败会抛出异常
                this._transferChannel.SendFile(filePath, this._fileTransferPolicy);
                Loger.Info($"发送文件\"{filePath}\"完成...");
            }
            catch (Exception ex)
            {
                Loger.Error(ex, $"发送文件\"{filePath}\"失败");
            }

            this.Invoke(new Action(() =>
            {
                btnSendFile.Enabled = true;
            }));
        }
    }
}
